﻿// =====================================================================
//
//  This file is part of the Microsoft Dynamics CRM SDK code samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//
// =====================================================================
using System;
using System.CodeDom.Compiler;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using System.ServiceModel;
using Microsoft.Xrm.Sdk.Temporary;

namespace Microsoft.Xrm.Sdk.Discovery
{

	[ServiceContract(Name = "IDiscoveryService", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	[ServiceKnownType(typeof(DiscoveryServiceFault))]
	public interface IDiscoveryService
	{
		[OperationContract(AsyncPattern = true)]
		[FaultContract(typeof(DiscoveryServiceFault))]
		System.IAsyncResult BeginExecute(DiscoveryRequest request, System.AsyncCallback callback, object asyncState);

		DiscoveryResponse EndExecute(System.IAsyncResult result);
	}


	[DataContract(Name = "DiscoveryRequest", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	[KnownType(typeof(RetrieveOrganizationRequest))]
	[KnownType(typeof(RetrieveOrganizationsRequest))]
	[KnownType(typeof(RetrieveUserIdByExternalIdRequest))]
	public abstract class DiscoveryRequest : IExtensibleDataObject
	{
		#region IExtensibleDataObject Implementation
		private ExtensionDataObject ExtensionDataObject;
		public ExtensionDataObject ExtensionData
		{
			get
			{
				return ExtensionDataObject;
			}
			set
			{
				ExtensionDataObject = value;
			}
		}
		#endregion IExtensibleDataObject Implementation
	}


	[DataContract(Name = "RetrieveUserIdByExternalIdRequest", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	public sealed class RetrieveUserIdByExternalIdRequest : DiscoveryRequest
	{
		/// <summary>
		/// The external id that is associated to a crmuserid
		/// </summary>
		[DataMember]
		public string ExternalId
		{
			get
			{
				return _externalId;
			}
			set
			{
				_externalId = value;
			}
		}

		/// <summary>
		/// The organization name to retrieve the CrmUserId for
		/// </summary>
		[DataMember]
		public string OrganizationName
		{
			get
			{
				return _organizationName;
			}
			set
			{
				_organizationName = value;
			}
		}

		[DataMember]
		public Guid OrganizationId
		{
			get
			{
				return _organizationId;
			}
			set
			{
				_organizationId = value;
			}
		}

		[DataMember]
		public string Release
		{
			get
			{
				return _release;
			}
			set
			{
				_release = value;
			}
		}


		private string _organizationName;
		private Guid _organizationId;
		private string _externalId;
		private string _release;
	}

	[DataContract(Name = "RetrieveOrganizationRequest", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	public sealed class RetrieveOrganizationRequest : DiscoveryRequest
	{
		[DataMember]
		public string UniqueName { get; set; }

		[DataMember(IsRequired = false)]
		public OrganizationRelease Release { get; set; }

		[DataMember(IsRequired = false)]
		public EndpointAccessType AccessType { get; set; }
	}

	[DataContract(Name = "RetrieveOrganizationsRequest", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	public sealed class RetrieveOrganizationsRequest : DiscoveryRequest
	{
		[DataMember(IsRequired = false)]
		public OrganizationRelease Release { get; set; }

		[DataMember(IsRequired = false)]
		public EndpointAccessType AccessType { get; set; }
	}


	[DataContract(Name = "DiscoveryResponse", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	[KnownType(typeof(RetrieveOrganizationResponse))]
	[KnownType(typeof(RetrieveOrganizationsResponse))]
	[KnownType(typeof(RetrieveUserIdByExternalIdResponse))]
	public abstract class DiscoveryResponse : IExtensibleDataObject
	{
		#region IExtensibleDataObject Implementation
		private ExtensionDataObject ExtensionDataObject;
		public ExtensionDataObject ExtensionData
		{
			get
			{
				return ExtensionDataObject;
			}
			set
			{
				ExtensionDataObject = value;
			}
		}
		#endregion IExtensibleDataObject Implementation
	}

	[DataContract(Name = "RetrieveOrganizationResponse", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	public sealed class RetrieveOrganizationResponse : DiscoveryResponse
	{
		[DataMember]
		public OrganizationDetail Detail { get; set; }
	}
	[DataContract(Name = "RetrieveOrganizationsResponse", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	public sealed class RetrieveOrganizationsResponse : DiscoveryResponse
	{
		private OrganizationDetailCollection _details = new OrganizationDetailCollection();

		[DataMember]
		public OrganizationDetailCollection Details { get { return _details; } internal set { _details = value; } }
	}

	/// <summary>
	/// Response to the RetrieveCrmUserIdByExternalIdRequest which returns the CrmUserId of external id provided.
	/// </summary>
	[DataContract(Name = "RetrieveUserIdByExternalIdResponse", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	public sealed class RetrieveUserIdByExternalIdResponse : DiscoveryResponse
	{
		/// <summary>
		/// The User Id for the provided external id.
		/// </summary>
		[DataMember]
		public Guid UserId
		{
			get
			{
				return _userId;
			}
			set
			{
				_userId = value;
			}
		}

		private Guid _userId;
	}

	[CollectionDataContract(Name = "OrganizationDetailCollection", Namespace = XmlNamespaces.V5.Discovery)]
	public sealed class OrganizationDetailCollection : DataCollection<OrganizationDetail>
	{
	}

	[DataContract(Name = "OrganizationDetail", Namespace = Microsoft.Xrm.Sdk.XmlNamespaces.V5.Discovery)]
	public sealed class OrganizationDetail : IExtensibleDataObject
	{
		[DataMember]
		public Guid OrganizationId
		{
			get { return _organizationId; }
			set { _organizationId = value; }
		}

		[DataMember]
		public string FriendlyName
		{
			get { return _friendlyName; }
			set { _friendlyName = value; }
		}

		[DataMember]
		public string OrganizationVersion
		{
			get { return _organizationVersion; }
			set { _organizationVersion = value; }
		}

		[SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Returned as string for compatibility")]
		[DataMember]
		public string UrlName { get; set; }

		[DataMember]
		public string UniqueName { get; set; }

		[DataMember]
		public EndpointCollection Endpoints { get { return _endpoints; } internal set { _endpoints = value; } }

		[DataMember]
		public OrganizationState State { get; set; }

		private EndpointCollection _endpoints = new EndpointCollection();
		private Guid _organizationId;
		private string _friendlyName;
		private string _organizationVersion;

		#region IExtensibleDataObject Implementation
		private ExtensionDataObject ExtensionDataObject;
		public ExtensionDataObject ExtensionData
		{
			get
			{
				return ExtensionDataObject;
			}
			set
			{
				ExtensionDataObject = value;
			}
		}
		#endregion IExtensibleDataObject Implementation
	}

	[GeneratedCode("System.Runtime.Serialization", "4.0.0.0")]
	[CollectionDataContract(Name = "EndpointCollection",
		Namespace = "http://schemas.microsoft.com/xrm/2011/Contracts/Discovery",
		ItemName = "KeyValuePairOfEndpointTypestringztYlk6OT")]
	public partial class EndpointCollection : Collection<KeyValuePairOfEndpointTypestringztYlk6OT>
	{
		public object this[EndpointType key]
		{
			get
			{
				foreach (KeyValuePairOfEndpointTypestringztYlk6OT item in this)
				{
					if (item.Key == key)
					{
						return item.Value;
					}
				}
				return null;
			}
		}

		public Boolean Contains(EndpointType key)
		{
			return (this[key] != null);
		}
	}

	[DataContract(Name = "EndpointType", Namespace = XmlNamespaces.V5.Discovery)]
	public enum EndpointType
	{
		[EnumMember]
		OrganizationService = 0,
		[EnumMember]
		OrganizationDataService,
		[EnumMember]
		WebApplication
	}

	[DataContract(Name = "EndpointAccessType", Namespace = XmlNamespaces.V5.Discovery)]
	public enum EndpointAccessType
	{
		[EnumMember]
		Default = 0, //Determines based on the URL
		[EnumMember]
		Internet,
		[EnumMember]
		Intranet
	}

	[DataContract(Name = "OrganizationState", Namespace = XmlNamespaces.V5.Discovery)]
	public enum OrganizationState
	{
		[EnumMember]
		Enabled = 0,
		[EnumMember]
		Disabled
	}

	[DataContract(Name = "OrganizationRelease", Namespace = XmlNamespaces.V5.Discovery)]
	public enum OrganizationRelease
	{
		[EnumMember]
		Current = 0,
		[EnumMember]
		V5
	}

	#region Legacy (Maintained here because there are other processes dependant on them on the server)
	/// <summary>
	/// A strongly typed property bag that gives details about each patch that needs to be installed
	/// on the client.
	/// </summary>
	public sealed class ClientPatchInfo
	{
		/// <summary>
		/// The PatchId of the patch that needs to be installed.
		/// </summary>

		public Guid PatchId
		{
			get { return _patchId; }
			set { _patchId = value; }
		}

		/// <summary>
		/// The Title of the Patch (eg: KB 1234)
		/// </summary>

		public string Title
		{
			get { return _title; }
			set { _title = value; }
		}

		/// <summary>
		/// A brief description of the patch (and what problem it resolves).
		/// </summary>

		public string Description
		{
			get { return _description; }
			set { _description = value; }
		}

		/// <summary>
		/// A bit to indicate if the patch is mandatory.
		/// </summary>

		public bool IsMandatory
		{
			get { return _isMandatory; }
			set { _isMandatory = value; }
		}

		/// <summary>
		/// The depth order in which this patch needs to be installed. Lower depth patches should be installed
		/// first.
		/// </summary>

		public int Depth
		{
			get { return _depth; }
			set { _depth = value; }
		}

		/// <summary>
		/// The link Identifier that is appended to the base URL when download patches.
		/// </summary>

		public String LinkId
		{
			get { return _linkId; }
			set { _linkId = value; }
		}

		private Guid _patchId;
		private string _title;
		private string _description;
		private bool _isMandatory;
		private int _depth;
		private String _linkId;
	}

	/// <summary>
	/// Notifications clients
	/// </summary>
	public enum EndUserNotificationClient
	{
		None = 0,
		WebApplication = 1,
		Portal = 2,
		Outlook = 3,
		Email = 4
	}

	/// <summary>
	/// A property bag encapsulating all the properties of the client that is requesting patches.
	/// </summary>
	public sealed class ClientInfo
	{
		#region Public members
		/// <summary>
		/// List of patches that the client already has installed.
		/// </summary>
		[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Need to pass in a list via SOAP which only supports arrays")]

		public Guid[] PatchIds
		{
			get { return _patchIds; }
			set { _patchIds = value; }
		}

		/// <summary>
		/// The type of client which is querying for patches. (Desktop\Laptop\DM Client).
		/// </summary>

		public ClientTypes ClientType
		{
			get { return _clientType; }
			set { _clientType = value; }
		}

		/// <summary>
		/// The CRM user id of the client.
		/// </summary>

		public Guid UserId
		{
			get { return _userId; }
			set { _userId = value; }
		}

		/// <summary>
		/// The Organization Id for which the client has been configured.
		/// </summary>

		public Guid OrganizationId
		{
			get { return _organizationId; }
			set { _organizationId = value; }
		}

		/// <summary>
		/// The language code for which the client has been configured.
		/// </summary>

		public int LanguageCode
		{
			get { return _languageCode; }
			set { _languageCode = value; }
		}

		/// <summary>
		/// The Office Version installed on the client machine.
		/// </summary>

		public String OfficeVersion
		{
			get { return _officeVersion; }
			set { _officeVersion = value; }
		}

		/// <summary>
		/// The operating system version that the client is running.
		/// </summary>

		public String OSVersion
		{
			get { return _osVersion; }
			set { _osVersion = value; }
		}

		/// <summary>
		/// The CRM version that the client is running.
		/// </summary>
		public String CrmVersion
		{
			get { return _crmVersion; }
			set { _crmVersion = value; }
		}
		#endregion

		#region Private members
		private Guid[] _patchIds;
		private ClientTypes _clientType;
		private Guid _userId;
		private Guid _organizationId;
		private int _languageCode;
		private String _officeVersion;
		private String _osVersion;
		private String _crmVersion;
		#endregion
	}
	[Flags]
	public enum ClientTypes
	{
		OutlookLaptop = 1,
		OutlookDesktop = 2,
		DataMigration = 4,
		OutlookConfiguration = 8,
		DataMigrationConfiguration = 16
	}
	#endregion Legacy
}
